<?php
/**
 * Drží orachannou ruku nad souborama a cestama
 * @author Michal Hantl
 * @version 0.0.1
 */
 
class cFile 
{
	
	function __construct(&$cms) 
	{
		$this->cms=$cms;
		$this->cms->dir = $this->getRelative($cms->fromDir,realpath(dirname(__FILE__)."/../")); //relativní cesta
		
		$this->groups = $this->listGroups(true);
	}
	
	function loadCore($name) 
	{
		include($this->cms->coreDir.$name.'.php');
	}
	
	
	
	/** Vrací XML definici node, s tou pracuje třída Node */
	function getDefinitionXML($group, $type)
	{
		if ($group=="" || $type=="") throw new cException("Group ($group), nebo type ($type) nejsou v pořádku!");
		
		if (!isset($this->groups[$group])) $group = $this->guessGroup($group);
		
		// onFly cache
		if ($cached = $this->cache['xmldefinitions'][$group][$type]) {
			return $cached;
		}
		
		$name = strToLower($type.".xml");
		
		$directory[] = 'groups/'.$group.'/nodes/'.$type.'/';
		$directory[] = $this->getNodeDir($group, $type);

		// nalezeni te spravne definice		
		foreach ($directory as $dir) {
			if (file_exists($fn=strToLower($dir.$name))) 
			{
				$found = true;
				break;
			}
		}
		if (!$found) throw new cException("Nenašel jsem šablonu $name");
		
		$xml = $this->read($fn);
		$xml = preg_replace("/<([A-z]+):([^ ]+) /e","'<\\2 group=\"'.\$this->guessGroup('\\1').'\" '",$xml);
		$xml = preg_replace("/<\/([A-z]+):([A-z]+)>/","</\\2>",$xml);

		// onFly cache
		$this->cache['xmldefinitions'][$group][$type] = $xml;
		
		return $xml;
	}
	
	function getNodeDir($group, $type) 
	{
		return $this->getGroupDir($group)."nodes/".$type."/";
	}

	function getPartDir($group, $type) 
	{
		return $this->getGroupDir($group)."parts/".$type."/";
	}

	function getGroupDir($group) 
	{
		return $this->cms->dir."groups/".$group."/";
	}
	
	function getXsl($group, $type, $view) 
	{
		//	jmeno sablony
		$name=$view->action."_".$view->lang."_".$view->doctype."_".$view->length."_".$view->mode.".xsl";

		//onFlyCache
		if (($xslProc = $this->cache["xsl"][$group][$type][$name]) instanceof XSLTProcessor) return $xslProc;

		//	slozky, ve kterych se sablona muze vyskytovat, sestupne podle priority 
		$directory[] = 'groups/'.$group.'/nodes/'.$type.'/';
		$directory[] = $this->getNodeDir($group, $type);
		$directory[] = $this->cms->dir."defaults/";

		// nalezeni te spravne sablony		
		foreach ($directory as $dir) {
			if (file_exists($xslFN=strToLower($dir.$name))) {
				$found = true;
				break;
			}
		}
		if (!$found) throw new cException("Nenašel jsem šablonu $name");
		
		
		$xsl = new XSLTProcessor();
		$xsl->importStyleSheet(DOMDocument::load($xslFN));
		
		//onFly Cache
		$this->cache["xsl"][$group][$type][$name] = $xsl;
		return $xsl;
	}
	
	function loadPart($group, $name)
	{
		$group = $this->guessGroup($group);
		$fn=strToLower($this->getPartDir($group, $name)."/".$name.".php");
		if (file_exists($fn)) {
			require_once($fn);
			return "p".$group."_".$name;
		} else return "cPart";
	}
	
	function guessGroup($shorty) 
	{
		$foundName=null;
		
		$shorty = strToLower($shorty);
		
		foreach ($this->groups as $gName=>$gTranslatedName) {
			if (substr($gName,0,strlen($shorty))==$shorty) {
				if ($foundName==null) {
					$foundName = $gName;
				} else {
					throw new cException("AWWW MAN! this '$shorty' can represent a whole bunch of groups! (like $foundName, or $gName)");
				}
			}
		}
		if ($foundName!=null) {
			return $foundName;		
		} else throw new cException("AWWW MAN! this '$shorty' doesn't represent anythang! Get him back to rap school, shiii."); 
	}

	function loadNode($group,$type)
	{
		$fn=strToLower($this->getNodeDir($group, $type).$type.".php");
		if (file_exists($fn)) {
			require_once($fn);
			return "t".$group."_".$type;
		} else return "tStandard_treeitem";
	}

	function loadGroup($group)
	{
		$fn=strToLower($this->getGroupDir($group).$group.".php");
		if (file_exists($fn)) {
			require_once($fn);
			return "g".$group;
		} else return "cGroup";
	}

	function listGroups($all = false)
	{
		$dir=strToLower($this->cms->dir."groups/");
		$group = $this->listFoldersIn($dir);
		foreach ($group as $g) {
			$gClass = $this->loadGroup($g);
			$gObj = new $gClass($this->cms);
			if ($all || $gObj->showInAdmin) {
				$out[strToLower($g)]=$gObj->getTranslated("name");
			}
		}
		return $out;
	}

	function getTypes($groups=null) 
	{
		return $this->listTypes();
	}
	
	function listTypes($groups=null)
	{
		$types = array();
		if ($groups==null) {
			$groups = $this->groups;
		}
		foreach ($groups as $group=>$translatedName) {
			$dir=strToLower($this->cms->dir."groups/".$group."/nodes/");
			$types = $this->listFoldersIn($dir);
			foreach ($types as $t) {
				$nClass = $this->loadNode($group, $t);
				$n = new $nClass($this->cms);
				$out[$group][$t]=$n->type; // TODO : hodit tam nejaky getTranslated
			}
		}
		return $out;
	}

	function listParts($groups=null)
	{
		$types = array();
		if ($groups==null) {
			$groups = $this->listGroups();
		}
		foreach ($groups as $group) {
			$dir=strToLower($this->getGroupDir($group)."/parts/");
			$types = $this->listFoldersIn($dir);
			foreach ($types as $t) {
				$nClass = $this->loadNode($group, $t);
				$n = new $nClass(null, $this->cms);
				$out[$group][$t]=$n->getTypeName();
			}
		}
		return $out;
	}

	/**
	 * Naincluduje t��du NODEu
	 */
	static function getNodeClassFilename($group, $type)
	{
		return strToLower("groups/".$group."/".$type."/".$type.".php");
	}

	/**
	 * dostane XML, ulo�� ho kam pat��
	 */
	function saveDefinition($group, $type, $xml)
	{
	}
	
	function saveNodeData(&$node)
	{
		$node->domData->formatOutput=true;
		$node->domData->save($this->getNodeXMLFilename($node));
	}

	function getNodeData(&$node)
	{
		return simplexml_load_file($this->getNodeXMLFilename($node));
	}
	
	function getNodeXMLFilename($node) {
		$sid = $this->xp->evaluate("/node/standard/string_id/")->item(0);
		return $this->cms->siteDir."xml/".$node->id."-".$node->type."-".$sid.".xml";
	}
	
	/* ==================================================== */
	/* ----------------- Práce se soubory ----------------- */
	/* ==================================================== */
	
	/** 
	 * $path relativní cesta ze siteDir
	 */
	function prepareFolder($path, $fromSitedir = true) 
	{
		if ($fromSitedir) { $dir = $this->cms->siteDir; } else $dir = $this->cms->dir;
		$folder = explode("/",$path);
		foreach ($folder as $f) 
		{
			$dir.=$f; //."/";
			if (!is_dir($dir)) {
				if (!@mkdir($dir, "0777")) {
					throw new cException("nepodařilo se vytvořit složku $dir");
				}
			}
			$dir.='/';
		}
		return $dir;
	}
	
  	function listFoldersIn($dir)
  	{
  		if (!is_dir($dir)) throw new cException("Chyba! ".$dir." není složka.");
    	$files=array();
    	$handle=opendir($dir);
   		rewinddir($handle);
   		while (($file = readdir($handle)))
   		{
       		if (is_dir($dir.$file) && $file[0]!=".") {
   	      		$files[]=$file;
       		}
   		}
    	return $files;
  	}

	/**
	 * Vr�t� seznam toho, co je v adres��i
	 */
  	function listDir($dir)
  	{
  		if (!is_dir($dir)) throw new cException ("Chyba! ".$dir." není složka.");
    	$files=array();
	    if ($handle=@opendir($dir))
	    {
    		rewinddir($handle);
      		while (($file = readdir($handle)))
      		{
        		if ($file[0]<>".") {
    	      		$files[]=$file;
        		}
      		}
    	}
    	return $files;
  	}
	
	/**
	 * Vr�t� obsah vzd�len�ho souboru
	 */  
  	function retrieveFile($url)
  	{
		$fp = @fopen($url, 'r');
		if (!$fp) {
			return false;
		}
		$temp = '';
		while (!feof($fp)) {
			$temp .= fgets($fp, 4096);
		}
		fclose ($fp);
		$fullpage = $temp;
		return $fullpage;
	}

  	 
  	/**
  	 * Vrac� obsah m�stn�ho souboru
  	 */
  	function read($fn)
  	{
    	if (file_exists($fn))
    	{
      		$f=fopen($fn,"r");
      		$t=fread($f,filesize($fn));
      		fclose($f);
    	  	return $t;
    	} else throw new cException("soubor $soubor neexistuje");
  	}
  	
  	/**
  	 * Zapise string do souboru
  	 */
  	function write($fn,$data)
  	{
    	$f=fopen($fn,"w+");
	    $t=fwrite($f,$data);
    	fclose($f);
	}

	/* Nejchytřejší funkce, vytváří relativní cesty
	 * 
	 */
	function getRelative($from, $to)
	{
		$from = str_replace("\\","/",$from);
		$to = str_replace("\\","/",$to);
		
		if ($chunk = strstr($from,"?")) {
			$from = substr($from, 0, -strlen($chunk));
		}
		if ($chunk = strstr($to,"?")) {
			$to = substr($to, 0, -strlen($chunk));
		}
		
		if (strlen(strrchr($from,"."))<1 && strlen($from)>0 && substr($from,-1)!="/") $from .="/";
		if (strlen(strrchr($to,"."))<1 && strlen($to)>0 && substr($to,-1)!="/") $to .="/"; 

		for ($i=0, $pos=0, $flen = strlen($from), $tlen = strlen($to);
			 $from[$i]==$to[$i] && $from[$i]!=null; $i++) 
		{ 
			if ($from[$i]=="/" || $i==$flen || $i==$tlen) $pos = $i+1;
		}

		$levelsUp = substr_count(substr($from,($pos)),"/");		
		if ($levelsUp>0) { $prefix = str_repeat("../",$levelsUp)."";} 

		return $prefix.substr($to,($pos));
	}	
}
?>